<template>
    <div style="height: 100%">
        <div :style="{ height: paging ? contentHeight : '100%', 'min-height': '140px' }">
            <vxe-table
                ref="xTable"
                :data="tableData"
                :row-id="tableConfig.rowKey"
                :resizable-config="{ minWidth: '50' }"
                :sort-config="{ defaultSort: $attrs.defaultSort || { field: '', order: '' }, remote: true }"
                :filter-config="{ remote: true }"
                :expand-config="{ iconOpen: 'el-icon-remove', iconClose: 'el-icon-circle-plus', toggleMethod }"
                :checkbox-config="{ strict: true, reserve: true, checkRowKeys: checkRowKeys, checkMethod: $attrs.checkMethod }"
                @sort-change="handleSort"
                @filter-change="handleFilter"
                @checkbox-change="checkboxChange"
                @checkbox-all="selectAllCheckboxChange"
                @cell-dblclick="handleDbclick"
                @cell-click="handleCellClick"
                @resizable-change="handleResize"
                @current-change="handleCurrentChange"
                v-bind="$attrs"
                auto-resize
                resizable
                stripe
                border
                size="mini"
                height="100%"
                show-header-overflow
                highlight-hover-row
                :highlight-current-row="highlightRow"
            >
                <vxe-column
                    v-for="item in column"
                    :key="item.field || item.prop || item.val"
                    v-bind="item"
                    :title="item.title || item.label || item.name"
                    :field="item.field || item.prop || item.val"
                    :sortable="item.sortable"
                    :filters="item.filters"
                    :align="item.align"
                    :fixed="item.fixed"
                    :width="item.width"
                    :min-width="item.minWidth || $attrs.minWidth || '50px'"
                    :show-overflow="getShowTooltip(item)"
                >
                    <template #filter="{ $panel, column }" v-if="item.filterType === 'search'">
                        <div>
                            <el-input
                                ref="searchInput"
                                class="my-input"
                                type="type"
                                v-for="(option, index) in column.filters"
                                :key="index"
                                v-model="option.data"
                                @input="$panel.changeOption($event, !!option.data, option)"
                            />
                        </div>
                    </template>

                    <template v-if="item.type === 'checkbox'" #header="{ checked, indeterminate }">
                        <!-- <span class="custom-checkbox" @click.stop="$refs.xTable.toggleAllCheckboxRow()">
                            <i v-if="indeterminate" class="vxe-icon-question-circle-fill"></i>
                            <i v-else-if="checked" class="vxe-icon-question-circle-fill"></i>
                            <i v-else class="vxe-icon-question-circle-fill"></i>
                        </span> -->
                        <span @click.stop>
                            <el-dropdown v-if="item.selectedAll" placement="bottom-start" trigger="click" @command="handleDropdown">
                                <span style="cursor: pointer">
                                    <i class="el-icon-arrow-down el-icon--right"></i>
                                </span>
                                <el-dropdown-menu slot="dropdown">
                                    <el-dropdown-item
                                        :command="item.value"
                                        v-for="item in [
                                            { text: '选中所有页', value: 'selectedAll' },
                                            { text: '取消所有页', value: 'cancelAll' },
                                        ]"
                                        :key="item.value"
                                        >{{ item.text }}</el-dropdown-item
                                    >
                                </el-dropdown-menu>
                            </el-dropdown>
                        </span>
                    </template>

                    <template v-if="item.type === 'expand'" #content="scope">
                        <slot name="expand" v-bind="scope"></slot>
                    </template>

                    <template #default="scope">
                        <!-- render渲染 优先级最高 -->
                        <span v-if="item.type == 'seq'">
                            {{ scope.$rowIndex + (paging.pageSize * (paging.currentPage - 1) + 1) }}
                        </span>
                        <span
                            v-else-if="item.render && typeof item.render === 'function'"
                            :style="getCellStyle(item, scope.row[item.field], scope.row)"
                        >
                            {{ item.render(scope.row[item.field || item.prop || item.val], scope.row) || '--' }}
                        </span>
                        <!-- 插槽渲染 slotName用于大部分字段用于同一种插槽展示内容时 -->
                        <slot
                            v-else-if="$scopedSlots[item.slotName || item.field || item.prop || item.val]"
                            :name="item.slotName || item.field || item.prop || item.val"
                            v-bind="{ ...scope, item }"
                        ></slot>
                        <span
                            v-else-if="item.type !== 'checkbox' && item.type !== 'expand'"
                            :style="getCellStyle(item, scope.row[item.field], scope.row)"
                        >
                            {{
                                scope.row[item.field || item.prop || item.val] === 0 ||
                                (scope.row[item.field || item.prop || item.val] && (scope.row[item.field || item.prop || item.val] + '').trim())
                                    ? scope.row[item.field || item.prop || item.val]
                                    : '--'
                            }}
                        </span>
                    </template>
                </vxe-column>
            </vxe-table>
        </div>

        <div v-if="paging && !$attrs.noshowPaging" class="block">
            <RiskPagination
                :paging="paging"
                :pageType="pageType"
                @page-change="$emit('page-change')"
                @pagesize-change="$emit('pagesize-change')"
            ></RiskPagination>
        </div>
    </div>
</template>

<script lang="ts">
import { Component, Vue, Prop, Watch, Emit } from 'vue-property-decorator';
import RiskPagination from '@/common/components/risk-pagination.vue';
import { VueObject, PageVO, TableConfigVO, ColumnVO } from '@/common/vo';
@Component({ name: 'RiskTableP', components: { RiskPagination } })
export default class RiskTableP extends Vue {
    @Prop() tableData: any[];
    @Prop() tableConfig: TableConfigVO;
    @Prop() column: ColumnVO[];
    @Prop() paging: PageVO;
    @Prop() sort: string;
    @Prop() searchParams: any;
    @Prop({
        default: 'calc(100%  - 58px)',
    })
    contentHeight: any;

    @Prop({
        default: () => {
            return true;
        },
    })
    showTooltip: any;

    @Prop({ default: false }) highlightRow: boolean;
    @Prop() pageType: string;

    selectionRows: any[] = [];
    checkRowKeys: any[] = []; // 已勾选数据
    checkedRows: any[] = [];
    selectedAll: boolean = false;
    cancelAll: boolean = false;

    /**
     * 监听表格数据发生变化时渲染勾选
     */
    @Watch('tableData', { deep: true })
    WatchTableData(newData: any, oldData: any) {
        if (this.selectedAll && !this.cancelAll) {
            newData.forEach(element => {
                if (this.checkRowKeys.includes(element[this.tableConfig.rowKey])) {
                    this.$nextTick(() => {
                        (this.$refs['xTable'] as VueObject).setCheckboxRow(element, true);
                    });
                }
            });
        }
        console.log('已勾选项:', this.checkRowKeys);
    }

    /**
     * 监听页码发生变化时渲染勾选
     */
    // @Watch('paging', { immediate: true, deep: true })
    // WatchPaging(newData: any, oldData: any) {}

    /**
     * 监听列发生变化时渲染放大镜icon
     * @remark
     */
    @Watch('column', { immediate: true, deep: true })
    WatchColumn(newData: any, oldData: any) {
        this.$nextTick(() => {
            // 需要改icon的列
            const magnifyingGlass = newData.filter(i => i.filterType === 'search').map(i => i.field);
            // 所有列dom
            const cols = (this.$refs['xTable'] as VueObject).getColumns();
            // 找到需要改icon的列domids
            let magnifyingGlassDomIds = [];
            cols.forEach(element => {
                if (magnifyingGlass.includes(element.property)) {
                    magnifyingGlassDomIds.push(element);
                }
            });
            magnifyingGlassDomIds.forEach(ele => {
                const colid = ele.id;
                if (ele.fixed) {
                    setTimeout(() => {
                        (this.$refs['xTable'] as VueObject).$el.querySelector(
                            `.vxe-table--fixed-left-wrapper th[data-colid=${colid}] .vxe-icon--funnel`
                        ).className = 'vxe-filter--btn el-icon-search';
                    });
                } else {
                    (this.$refs['xTable'] as VueObject).$el.querySelector(`th[data-colid=${colid}] .vxe-icon--funnel`).className =
                        'vxe-filter--btn el-icon-search';
                }
            });
        });
    }

    /**
     * 监听checkRowKeys
     */
    @Watch('checkRowKeys', { deep: true })
    changeCheckedKeys() {
        this.$emit('checkRowKeys-change', this.checkRowKeys);
    }

    mounted() {
        // debugger;
        // console.log((this.$attrs['checkbox-config'] as any)(), '$attrs');
        // console.log(this.$attrs.checkboxConfig());
        // 清除 原生HTML title
        // this.$nextTick(() => {
        //     ((this.$refs['xTable'] as VueObject) as any).$el.querySelector('span[title="全选/取消"]').title = '';
        // });
    }

    /**
     * 动态显示tooltip
     */
    getShowTooltip(item) {
        if (!this.showTooltip) {
            return 'ellipsis';
        } else {
            if (item.notShowTooltip) {
                return 'ellipsis';
            } else {
                return item.notShowTooltip ?? 'tooltip';
            }
        }
    }

    /**
     * 选中/取消 所有页事件
     */
    handleDropdown(value: string): void {
        if (value === 'selectedAll') {
            this.selectedAll = true;
            this.cancelAll = false;
            this.$emit('getAllData');
        }
        if (value === 'cancelAll') {
            this.selectedAll = false;
            this.cancelAll = true;
            this.checkRowKeys = [];
            this.checkedRows = [];
            (this.$refs['xTable'] as VueObject).clearCheckboxRow();
            (this.$refs['xTable'] as VueObject).clearCheckboxReserve();
        }
        console.log('已勾选项:', this.checkRowKeys);
    }

    handleSelectAll() {
        this.checkRowKeys = this.tableConfig.allRowKeys;
        if (this.tableConfig.allRows) {
            this.checkedRows = this.tableConfig.allRows;
        }
        (this.$refs['xTable'] as VueObject).setAllCheckboxRow(true);
        console.log('已勾选项:', this.checkRowKeys);
    }

    /**
     * 表格复选框勾选事件
     */
    checkboxChange({ records, checked, row }): void {
        if (checked) {
            this.checkedRows.push(row);
            this.checkRowKeys.push(row[this.tableConfig.rowKey]);
        } else {
            this.checkedRows = this.checkedRows.filter(item => item[this.tableConfig.rowKey] !== row[this.tableConfig.rowKey]);
            this.checkRowKeys = this.checkRowKeys.filter(i => i !== row[this.tableConfig.rowKey]);
        }
        console.log('已勾选项:', this.checkedRows, this.checkRowKeys);
    }

    /**
     * 表格复选框勾选事件
     */
    selectAllCheckboxChange({ records, checked }): void {
        if (checked) {
            const checkedKeys = records.map(i => i[this.tableConfig.rowKey]);
            const newArr = records.filter(item => !this.checkRowKeys.includes(item[this.tableConfig.rowKey]));
            this.checkRowKeys = [...new Set(this.checkRowKeys.concat(checkedKeys))];
            this.checkedRows = this.checkedRows.concat(newArr);
        } else {
            const checkedKeys = this.tableData.map(i => i[this.tableConfig.rowKey]);
            this.checkRowKeys = this.filterArr(this.checkRowKeys, checkedKeys);
            this.checkedRows = this.checkedRows.filter(item => !checkedKeys.includes(item[this.tableConfig.rowKey]));
        }
        console.log('已勾选项:', this.checkRowKeys);
    }

    /**
     * 表格排序事件
     */
    // @Emit('page-change')
    handleSort({ property, order }): void {
        let sort = '';
        let sortField = '';
        if (order) {
            sortField = this.column.find(i => i.field === property)?.sortField || property;
            sort = (sortField + ' ' + order).toUpperCase();
        }
        this.paging && (this.paging.currentPage = 1);
        this.searchParams['sort'] = sort;

        this.$emit('page-change', { sortField, property, order, sort, type: 'sort' });
        this.$emit('sort-change', { sortField, property, order, sort, type: 'sort' });
        // this.$emit('update:sort', sort);
    }

    /**
     * 表格搜索/筛选事件
     */
    // @Emit('page-change')
    handleFilter({ field, values, datas }): void {
        const col = this.column.find(i => i.field === field);
        // 漏洞用values 放大镜用datas
        let searchParams = this.searchParams;
        // searchParams[field] = values.filter(Boolean).length ? values : datas.join('');
        searchParams[col.filterField ?? field] = col.filterType === 'search' ? datas.join('') : values;
        this.paging && (this.paging.currentPage = 1);
        this.$emit('update:searchParams', searchParams);
        this.$emit('page-change', 'filter');
    }

    /**
     * 单元格双击事件
     */
    @Emit('cell-dblclick')
    handleDbclick({ row }): any {
        return row;
    }
    /**
     * 单元格点击
     */
    @Emit('cell-click')
    handleCellClick($event) {
        return $event;
    }
    /**
     * 切换选中行事件
     */
    @Emit('current-change')
    handleCurrentChange($event) {
        return $event;
    }

    /**
     * 列宽拖动事件
     */
    @Emit('resize-change')
    handleResize({ column }) {
        // console.log(column, 'column');
        // return {  column.property: column.resizeWidth };
        let obj = {};
        this.$set(obj, column.property, column.resizeWidth);
        return obj;
    }

    isTemplateCell(row: any): boolean {
        // 插槽
        if (this.$scopedSlots[row.prop || row.val || row.field]) {
            return true;
        }
        // render
        if (row.render && typeof row.render === 'function') {
            return true;
        }
        return false;
    }

    getCellStyle(col: any, value: any, record: any): any {
        if (col.style && typeof col.style === 'function') {
            return col.style(value, record);
        } else if (col.style && typeof col.style === 'object') {
            return col.style;
        } else {
            return null;
        }
    }

    /**
     * 两个对象数组, 筛选出数组一不包含数组二的元素
     */
    filterArr(arr1: string[], arr2: string[]): string[] {
        let uid1 = [];
        let uid2 = [];
        for (let i in arr1) {
            uid1.push(arr1[i]);
        }
        for (let i in arr2) {
            uid2.push(arr2[i]);
        }
        const arr = [...uid1, ...uid2];
        const newArr = arr.filter(item => {
            return !(uid1.includes(item) && uid2.includes(item));
        });
        return newArr;
    }

    /**
     * 清空已勾选数据
     */
    resetCheckRowKeys() {
        this.handleDropdown('cancelAll');
    }

    /**
     * 重置查询条件
     */
    clearFilter() {
        (this.$refs['xTable'] as any).clearFilter();
    }
}
</script>

<style lang="scss" scoped>
.my-input {
    margin: 10px;
    width: 150px;
}

/deep/ .vxe-table {
    width: 100%;
}

/deep/ .vxe-table .el-button + .el-button {
    margin-left: 0;
}

/deep/ .vxe-table .vxe-table--header {
    width: 10px !important;
}
</style>
